// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "TextAssetActions.h"

#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "TextAsset.h"
#include "Styling/SlateStyle.h"

#include "TextAssetEditorToolkit.h"


#define LOCTEXT_NAMESPACE "AssetTypeActions"


/* FTextAssetActions constructors
 *****************************************************************************/

FTextAssetActions::FTextAssetActions(const TSharedRef<ISlateStyle>& InStyle)
	: Style(InStyle)
{ }


/* FAssetTypeActions_Base overrides
 *****************************************************************************/

bool FTextAssetActions::CanFilter()
{
	return true;
}

//使得我们的类可以扩展快捷菜单，它需要传入两个参数来实现该功能
//一个是右键点击的对象集合，在编辑器中可以同时点击多个对象
//第一个参数注意这里传入的是UObject*类型，因为我们其实无法确定会传入何种资源，
//第二个参数 是菜单构建器，这个允许我们在显示菜单中增加新的选项
void FTextAssetActions::GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder)
{
	FAssetTypeActions_Base::GetActions(InObjects, MenuBuilder);

	//注意这里，GetTypeWeakObjectPtrs这个操作会确保我们对象指针不会丢失，
	//因为新对象实际上可能会被垃圾回收掉，这意味着继续使用指向这些对象的C++裸指针，垃圾回收器可能会删除，并销毁这些对象，我们的指针可能指向
	//无效的内存区域，如果我们试图解引用就会程序崩溃
	//办法是获取一组“弱对象指针”，这意味着这组新对象的裸指针会被转换成一组所谓的弱指针，这些弱指针能在垃圾回收器决定销毁引用对象时，自动重置
	//我们在操作时可能有时间间隔，导致过程中资源发生变化
	auto TextAssets = GetTypedWeakObjectPtrs<UTextAsset>(InObjects);

	//FUIAction两个操作，一个函数决定是否可以执行操作，一个是执行时的函数
	MenuBuilder.AddMenuEntry(
		LOCTEXT("TextAsset_ReverseText", "Reverse Text"),
		LOCTEXT("TextAsset_ReverseTextToolTip", "Reverse the text stored in the selected text asset(s)."),
		FSlateIcon(),
		FUIAction(
			FExecuteAction::CreateLambda([=]{
				for (auto& TextAsset : TextAssets)
				{
					if (TextAsset.IsValid() && !TextAsset->Text.IsEmpty())
					{
						TextAsset->Text = FText::FromString(TextAsset->Text.ToString().Reverse());
						TextAsset->PostEditChange();
						TextAsset->MarkPackageDirty();
					}
				}
			}),
			FCanExecuteAction::CreateLambda([=] {
				for (auto& TextAsset : TextAssets)
				{
					if (TextAsset.IsValid() && !TextAsset->Text.IsEmpty())
					{
						return true;
					}
				}
				return false;
			})
		)
	);
}

//用于确定资源再快捷菜单中被归在哪一类
uint32 FTextAssetActions::GetCategories()
{
	return EAssetTypeCategories::Misc;
	//可以出现再快捷菜单中的多个地方 用|增加
	//return EAssetTypeCategories::Misc | EAssetTypeCategories::Blueprint;
}

//返回资源的名字，也就是缩略图中显示的文本字符串
FText FTextAssetActions::GetName() const
{
	return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_TextAsset", "Text Asset");
}

//这个资源操作应该用于UTextAsset类，必须实现这个函数
UClass* FTextAssetActions::GetSupportedClass() const
{
	return UTextAsset::StaticClass();
}

//缩略图的颜色
FColor FTextAssetActions::GetTypeColor() const
{
	return FColor::White;
}

//用于决定传入对象，如果函数返回真，编辑器将调用GetActions
bool FTextAssetActions::HasActions(const TArray<UObject*>& InObjects) const
{
	return true;
}

//实现自定义用户界面
void FTextAssetActions::OpenAssetEditor(const TArray<UObject*>& InObjects, TSharedPtr<IToolkitHost> EditWithinLevelEditor)
{
	EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid()
		? EToolkitMode::WorldCentric
		: EToolkitMode::Standalone;

	for (auto ObjIt = InObjects.CreateConstIterator(); ObjIt; ++ObjIt)
	{
		auto TextAsset = Cast<UTextAsset>(*ObjIt);

		if (TextAsset != nullptr)
		{
			TSharedRef<FTextAssetEditorToolkit> EditorToolkit = MakeShareable(new FTextAssetEditorToolkit(Style));
			EditorToolkit->Initialize(TextAsset, Mode, EditWithinLevelEditor);
		}
	}
}


#undef LOCTEXT_NAMESPACE
